package com.itheima.stock.service.impl;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.itheima.stock.common.domain.InnerMarketDomain;
import com.itheima.stock.common.domain.StockExcelDomain;
import com.itheima.stock.common.domain.StockUpdownDomain;
import com.itheima.stock.config.vo.StockInfoConfig;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.pojo.StockRtInfo;
import com.itheima.stock.service.StockService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.vo.resp.PageResult;
import com.itheima.stock.vo.resp.R;
import com.itheima.stock.vo.resp.ResponseCode;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("stockService")
public class StockServiceImpl implements StockService {

    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockInfoConfig stockInfoConfig;

    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    @Override
    public List<StockBusiness> findAll() {
        return stockBusinessMapper.findAll();
    }

    @Override
    public R<List<InnerMarketDomain>> getNewAMarketInfo() {
        //获取A股大盘的id集合
        List<String> inners = stockInfoConfig.getInner();
        //获取最近股票交易日期
        DateTime lastDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //转java中的date
        Date lastDate = lastDateTime.toDate();
        //TODO mock测试
        lastDate = DateTime.parse("2022-01-03 11:15:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
        //将获取的java date 传入接口
        List<InnerMarketDomain> list = stockMarketIndexInfoMapper.getMarketInfo(inners, lastDate);
        //返回查询结果
        return R.ok(list);

    }

    @Override
    public R<List<StockUpdownDomain>> getStockInfoLimit() {
        //1.获取最近最新的股票交易时间点
        Date lastDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDate();
        //TODO mock测试
        lastDate = DateTime.parse("2021-12-30 09:42:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
        //2.调用Mapper查询
        List<StockUpdownDomain> list = stockRtInfoMapper.getStockInfoLimit(lastDate);
        //判断集合状态
        if (CollectionUtils.isEmpty(list)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        return R.ok(list);
    }

    @Override
    public R<PageResult<StockUpdownDomain>> getStockInfo4Page(Integer page, Integer pageSize) {
        //1.设置分页参数
        PageHelper.startPage(page, pageSize);
        //2.查询
        List<StockUpdownDomain> pages = stockRtInfoMapper.getStockInfo4All();
        if (CollectionUtils.isEmpty(pages)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        //3.组装PageInfo对象
        PageInfo<StockUpdownDomain> pageInfo = new PageInfo<>(pages);
        //4.转换成自定义的分页对象
        PageResult<StockUpdownDomain> pageResult = new PageResult<>(pageInfo);
        return R.ok(pageResult);
    }

    @Override
    public R<Map> getStockUpdownCount() {
        //1.获取最近交易日的开收盘日期
        DateTime avableTimePoint = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date openTime = DateTimeUtil.getOpenDate(avableTimePoint).toDate();
        Date closeTime = DateTimeUtil.getCloseDate(avableTimePoint).toDate();
        //TODO mock测试数据
        openTime = DateTime.parse("2021-12-19 09:30:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
        closeTime = DateTime.parse("2021-12-19 15:30:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
        //2.查询涨停的统计数据
        List<Map> upList = stockRtInfoMapper.getStockUpdownCount(openTime, closeTime, 1);
        //3.查询跌停的统计数据
        List<Map> dowmList = stockRtInfoMapper.getStockUpdownCount(openTime, closeTime, 0);
        //4.组装map:将涨跌停的数据组装的map集合中
        HashMap<String, List> map = new HashMap<>();
        map.put("upList", upList);
        map.put("downList", dowmList);
        //5.返回结果
        return R.ok(map);
    }

    @Override
    public void stockExport(HttpServletResponse response, Integer page, Integer pageSize) throws IOException {
        //1.设置响应数据的类型:excel
        response.setContentType("application/vnd.ms-excel");
        //2.设置响应数据的编码格式
        response.setCharacterEncoding("utf-8");
        //3.设置默认的文件名称
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("stockRt", "UTF-8");
        //设置默认文件名称
        response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
        //读取导出的数据集合
        //1.设置分页参数
        PageHelper.startPage(page, pageSize);
        //2.查询
        List<StockUpdownDomain> pages = stockRtInfoMapper.getStockInfo4All();
        if (CollectionUtils.isEmpty(pages)) {
            R<String> error = R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
            //将错误信息转化为json字符串相应前端
            String jsonData = new Gson().toJson(error);
            //响应前端错误数据
            response.getWriter().write(jsonData);
            //终止程序
            return;
        }
        //将List<StockUpdownDomain>转化成List<StockExcelDomain>
        List<StockExcelDomain> domains = pages.stream().map(item -> {
            StockExcelDomain domain = new StockExcelDomain();
            BeanUtils.copyProperties(item, domain);
            return domain;
        }).collect(Collectors.toList());
        //数据导出
        EasyExcel
                .write(response.getOutputStream(),StockExcelDomain.class)
                .sheet("stockInfo")
                .doWrite(domains);
    }
}
